/**
 * $Revision: 1.0 $
 * $Author: Eric Yang $
 * $Date: Aug 7, 2009 10:38:54 PM $
 *
 * Author: Eric Yang
 * Date  : Aug 7, 2009 10:38:54 PM
 *
 */
package com.gooex.service.base.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;
import org.c4j.date.DateTools;
import org.c4j.string.StringTools;
import org.c4j.system.web.exception.ServiceException;
import org.c4j.system.web.page.Page;

import com.gooex.domain.base.Category;
import com.gooex.domain.base.Order;
import com.gooex.domain.base.OrderCustomer;
import com.gooex.domain.base.OrderQuote;
import com.gooex.domain.base.OrderRequest;
import com.gooex.domain.base.OrderVendor;
import com.gooex.domain.base.Product;
import com.gooex.domain.base.PropertyValue;
import com.gooex.domain.base.TempCategory;
import com.gooex.domain.base.emun.OrderStatus;
import com.gooex.domain.common.Region;
import com.gooex.domain.company.Company;
import com.gooex.domain.organization.Address;
import com.gooex.domain.organization.User;
import com.gooex.service.BaseAppHibernateService;
import com.gooex.service.base.ICategoryManager;
import com.gooex.service.base.IOrderManager;
import com.gooex.service.base.IOrderNotifier;
import com.gooex.service.base.IPropertyManager;
import com.gooex.service.base.exception.ExceptionCode;
import com.gooex.service.base.exception.OrderException;
import com.gooex.service.company.ICompanyManager;
import com.gooex.service.organization.IUserManager;

/**
 * 对于数据库异常的处理在AOP中实现（也可以在拦截器中实现），所以暂不处理数据库异常
 * 
 * @author Eric Yang
 * @author Adolf
 * @version 1.0
 */
@SuppressWarnings( { "unused", "unchecked" })
public class OrderManagerImpl extends BaseAppHibernateService implements IOrderManager {

	private static final Log logger = LogFactory.getLog(OrderManagerImpl.class);

	private static final String yyMMdd = "yyMMdd";

	private IUserManager userManager;

	private ICompanyManager companyManager;

	private IPropertyManager propertyManager;

	private IOrderNotifier orderNotifier;

	private ICategoryManager categoryManager;

	public OrderManagerImpl() {
	}

	public Order getOrder(String id) {
		if (StringTools.isBlankOrNull(id)) {
			logger.debug("Null id to get Order");
			return null;
		}
		return getObject(Order.class, id);
	}

	public OrderCustomer getOrderCustomer(String customerId) {
		return getObject(OrderCustomer.class, customerId);
	}

	public OrderVendor getOrderVendor(String vendorId) {
		return getObject(OrderVendor.class, vendorId);
	}

	public void removeOrder(Order order) throws OrderException {
		order = getOrder(order.getId());
		getHibernateTemplate().delete(order);
	}

	public List<Order> getOrders() {
		return getHibernateTemplate().find("from Order");
	}

	public List<Order> getOrders(OrderStatus status, Page page) {
		Criteria criteria = getSession().createCriteria(Order.class).setCacheable(true).add(Restrictions.eq("status", status));
		org.hibernate.criterion.Order o = new org.hibernate.criterion.Order("comfirmDate", true) {

		};
		criteria = criteria.addOrder(o);
		if (page != null) {
			int start = (page.getCurrentPage() - 1) * page.getPageSize();
			if (start >= page.getRecordCount())
				start = page.getRecordCount() - 1;
			criteria.setFirstResult(start);
			criteria.setMaxResults(page.getPageSize());
		}
		return criteria.list();
	}

	public Order getOrderByTitle(String name) {
		String hql = "from " + Order.class.getName() + " WHERE title = ?";
		List<Order> orders = getHibernateTemplate().find(hql, name);
		if (orders != null && orders.size() == 1)
			return orders.get(0);

		logger.debug("No order found for search key[" + name + "]");
		return null;
	}

	public List<Order> findOrderByTitle(List<String> keys, String cateId, String region, Page page) {
		List<Object> parameters = new ArrayList<Object>();
		String queryString = "from " + Order.class.getName() + " WHERE  status < ?";
		parameters.add(OrderStatus.CLOSED);
		if (keys != null && keys.size() > 0) {
			queryString += " and ( 1!=1 ";
			for (int i = 0; i < keys.size(); i++) {
				queryString += " or title like ?";
				parameters.add("%" + keys.get(i) + "%");
			}
			queryString += " ) ";
		}

		if (StringTools.isNotBlankOrNull(region) && !Region.GLOBAL_REGION.equals(region)) {
			queryString += " and vendorRegion.id like ?";
			parameters.add(region + "%");
		}

		if (StringTools.isNotBlankOrNull(cateId)) {
			queryString += " and (category.id=? or category.parent.id=? or category.parent.parent.id=?)";
			parameters.add(cateId);
			parameters.add(cateId);
			parameters.add(cateId);
		}

		queryString += " order by updatedTime desc";

		if (page == null) {
			page = new Page();
		}
		return findHQLQuery(queryString, parameters.toArray(), page);
	}

	public void saveOrder(Order order) {
		boolean isNewOrder = StringTools.isBlankOrNull(order.getId());
		if (isNewOrder) {
			order.setId(generateSerialCode(order));
		}
		order.setUpdatedTime(new Date());
		getHibernateTemplate().saveOrUpdate(order);

		/* set category count */
		Category category = order.getCategory();
		if (isNewOrder) {
			categoryManager.increaseCount(category, order.getVendorRegion().getId());
		} else {
			OrderStatus status = order.getStatus();
			if (status.isClosed() || status.isCanceled()) {
				categoryManager.decreaseCount(category, order.getVendorRegion().getId());
			}
		}
	}

	public void createOrder(Order order) {
		// 判断基本参数值是否存在
		// propertyManager.assertPropertiesExists(order.getBasePropertyValues());
		this.saveOrder(order);
	}

	public List<Order> getTopNewOrders(String regionId, Page page) {
		if (page == null) {
			page = new Page();
			page.setPageSize(30);
		}
		page.setCurrentPage(1);
		String queryString = "FROM Order Where status in (?,?,?,?)";

		List<Object> parameters = new ArrayList<Object>();
		parameters.add(OrderStatus.INVITING);
		parameters.add(OrderStatus.QUOTING);
		parameters.add(OrderStatus.VOTING);
		parameters.add(OrderStatus.CONFIRMED);
		if (StringTools.isNotBlankOrNull(regionId) && !Region.GLOBAL_REGION.equals(regionId)) {
			queryString += " and vendorRegion.id like ?";
			parameters.add(regionId + "%");
		}

		queryString += " ORDER BY updatedTime DESC";

		final String hql = queryString;
		QueryCallBack callback = new QueryCallBack() {
			public Query createQuery(Session session) {
				return session.createQuery(hql);
			}
		};

		return find(parameters.toArray(new Object[] {}), page, callback);
	}

	/**
	 * @see com.gooex.service.base.IOrderManager#preAddOrder(java.util.List)
	 */
	public Order preAddOrder(List<PropertyValue> propertyValues) {
		propertyManager.assertPropertiesExists(propertyValues);

		Order order = new Order();
		// order.setBasePropertyValues(propertyValues);

		return order;
	}

	/**
	 * @see com.gooex.service.base.IOrderManager#addOrderCustomer(java.lang.String, com.gooex.domain.base.OrderCustomer)
	 */
	public void addOrderCustomer(String id, OrderCustomer orderCustomer) {
		// 订单要存在
		Order order = assertOrderExists(id);

		// 加入订单的产品要存在
		assertOrderProductsExists(orderCustomer.getOrderRequests());
		orderCustomer.setOrder(order);
		order.addCustomer(orderCustomer);

		order.setCustomerCount(order.getCustomers().size());
		saveOrder(order);

		/* 同步订单请求信息 */
		syncRequestAndQuote(orderCustomer);
	}

	public List<Order> getOwnCreateOrder(String userId, Page page) {
		Object[] params = new Object[] { userId };
		String queryStr = "FROM Order o Where o.createUser.id = ?";
		return findHQLQuery(queryStr, params, page);
	}

	public List<Order> getParticipateOrder(String userId, Page page) {
		Object[] params = new Object[] { userId };
		String queryStr = "from Order o where o.id in (select c.order.id FROM OrderCustomer c Where c.user.id=? )";
		return findHQLQuery(queryStr, params, page);
	}

	public List<Order> getOrders(Page page) {
		return findHQLQuery("FROM Order", null, page);
	}

	@Transactional
	public void cancelOrderRequest(String id) {
		OrderRequest request = getOrderRequest(id);
		Order order = request.getOrderCustomer().getOrder();
		List<OrderRequest> requests = request.getOrderCustomer().getOrderRequests();
		if (requests == null || requests.size() == 0) {
			return;
		} else if (requests.size() == 1) {
			// 用户对此订单只有一个请求
			getHibernateTemplate().delete(request);
			getHibernateTemplate().delete(request.getOrderCustomer());
		} else {
			// 用户对此订单有多个请求
			getHibernateTemplate().delete(request);
		}
		syncOrderInfo(order);
	}

	private OrderRequest getOrderRequest(String id) {
		OrderRequest request = (OrderRequest) getHibernateTemplate().get(OrderRequest.class.getName(), id);
		if (request == null) {
			throw new ServiceException(ExceptionCode.ORDER_REQUEST_NOT_EXISTS, "No order request!");
		}

		OrderCustomer customer = request.getOrderCustomer();

		Query q0 = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery("FROM OrderRequest o Where o.orderCustomer.id=?");
		q0.setString(0, customer.getId());
		customer.setOrderRequests(q0.list());

		return request;
	}

	/**
	 * 主要是设置当前用户的详细信息
	 * 
	 * @param orderRequest
	 */
	private void beforeSaveOrderRequest(OrderRequest orderRequest) {
		User user = this.userManager.getUserByAccount(orderRequest.getOrderCustomer().getUser().getEmail());

		if (user == null) {
			throw new ServiceException(ExceptionCode.USER_NOT_EXISTS, "User not exists!");
		}

		orderRequest.getOrderCustomer().setUser(user);
		List<PropertyValue> propertyValues = orderRequest.getPropertyValues();
		if (propertyValues != null && propertyValues.size() > 0) {
			String v = "";
			for (int i = 0; i < propertyValues.size(); i++) {
				PropertyValue p = propertyValues.get(i);
				p = propertyManager.getPropertyValue(p.getId());
				v += "[" + p.getProperty().getName() + "]:" + p.getValue() + "\r\n";
			}
			String comment = StringTools.isBlankOrNull(orderRequest.getComment()) ? v.substring(0, v.length() - 2) : v + orderRequest.getComment();
			orderRequest.setComment(comment);
		}
	}

	/**
	 * 如果用户本次提交的订单要求和上次提交的订单要求一致，也认为二者不一样， 暂不做同一性判断
	 */
	@Transactional
	public void saveOrderRequest(OrderRequest orderRequest) {

		beforeSaveOrderRequest(orderRequest);

		Order order = orderRequest.getOrderCustomer().getOrder();
		order = assertOrderExists(order.getId());

		User user = orderRequest.getOrderCustomer().getUser();
		OrderCustomer orderCustomer = getOrderCustomer(order.getId(), user.getId());

		if (orderCustomer == null) {
			Address address = orderRequest.getOrderCustomer().getAddress();

			orderCustomer = new OrderCustomer();

			orderCustomer.setUser(user);
			orderCustomer.setOrder(order);

			orderCustomer.setAddress(address);

			String id = (String) this.getHibernateTemplate().save(OrderCustomer.class.getName(), orderCustomer);
			orderCustomer.setId(id); // TODO to check whether this is needed
		}

		orderRequest.setPropertyValues(getPropertyValue(orderRequest));
		orderCustomer.addOrderRequest(orderRequest);
		getHibernateTemplate().save(OrderRequest.class.getName(), orderRequest);
		syncRequestAndQuote(orderCustomer);
	}

	private List<PropertyValue> getPropertyValue(OrderRequest orderRequest) {
		List<PropertyValue> tps = orderRequest.getPropertyValues();
		if (tps == null || tps.size() == 0) {
			// 如果页面未选择任何参数值 我们也应该视为正确的
			return tps;
		}

		List<PropertyValue> targets = new ArrayList<PropertyValue>(tps.size());
		for (PropertyValue item : orderRequest.getPropertyValues()) {
			PropertyValue temp = propertyManager.getPropertyValue(item.getProperty().getId(), item.getId());

			if (temp == null) {
				throw new ServiceException(ExceptionCode.PROPERTY_VALUE_NOT_EXISTS, "");
			}

			targets.add(temp);
		}
		return targets;
	}

	public OrderCustomer getOrderCustomer(Order order, User user) {
		return getOrderCustomer(order.getId(), user.getId());
	}

	public OrderCustomer getOrderCustomer(Order order, String customerId) {
		String sql = "FROM OrderCustomer WHERE order.id = ? AND id = ? ";
		List<OrderCustomer> orderCustomers = getHibernateTemplate().find(sql, new Object[] { order.getId(), customerId });

		if (orderCustomers != null && orderCustomers.size() > 0)
			return orderCustomers.get(0);

		logger.debug("No customer found");
		return null;
	}

	public OrderCustomer getOrderCustomer(String orderId, String userId) {
		String sql = "FROM OrderCustomer WHERE order.id = ? AND user.id = ? ";
		List<OrderCustomer> orderCustomers = getHibernateTemplate().find(sql, new Object[] { orderId, userId });

		if (orderCustomers != null && orderCustomers.size() > 0)
			return orderCustomers.get(0);

		logger.debug("No customer found");
		return null;

	}

	public List<Order> getOrdersByProduct(Product product) {
		if (product == null || StringUtils.isBlank(product.getId())) {
			return new ArrayList<Order>();
		}
		String hql = "from " + Order.class.getName() + " WHERE product.id=?";
		return findHQLQuery(hql, new Object[] { product.getId() }, null);
	}

	public void updateOrder(Order order) {
		this.createOrder(order);
	}

	private void assertOrderProductsExists(List<OrderRequest> orderRequests) {

	}

	public String generateSerialCode() {
		throw new RuntimeException("can't invoke this method");
	}

	/**
	 * @param obj
	 *            订单对象
	 * @return 产生订单号
	 */
	public String generateSerialCode(Object obj) {
		try {
			Order order = (Order) obj;
			String id = order.getCategory().getId();
			String date = DateTools.format(new Date(), yyMMdd);
			int count = findHQLQueryCount("SELECT count(*) FROM " + Order.class.getName() + " WHERE id like ?", new String[] { id + date + "%" });
			count++;
			return id + date + StringTools.buildNumber(count + "", 8, 0, false, true);
		} catch (Exception e) {
			throw new RuntimeException(ExceptionCode.ORDER_CODE_GENERATE_ERROR);
		}
	}

	public Order assertOrderExists(String id) {
		Order order = this.getOrder(id);
		if (order == null) {
			throw new ServiceException(ExceptionCode.ORDER_NOT_EXISTS, "the order is not exists!");
		}
		return order;
	}

	public void syncRequestAndQuote(Order order) {
		order = getOrder(order.getId());
		List<OrderCustomer> customers = order.getCustomers();
		List<OrderVendor> vendors = order.getVendors();
		for (int i = 0; i < customers.size(); i++) {
			OrderCustomer orderCustomer = customers.get(i);
			for (int j = 0; j < vendors.size(); j++) {
				OrderVendor orderVendor = vendors.get(j);
				syncRequestAndQuote(orderCustomer, orderVendor);
			}
		}
	}

	public void syncRequestAndQuote(Order order, OrderVendor orderVendor) {
		order = getOrder(order.getId());
		if (!orderVendor.getOrder().equals(order))
			throw new ServiceException(ExceptionCode.SYSTEM_INVOKE_ERROR, "");

		List<OrderCustomer> customers = order.getCustomers();
		for (int i = 0; i < customers.size(); i++) {
			OrderCustomer orderCustomer = customers.get(i);
			syncRequestAndQuote(orderCustomer, orderVendor);
		}
		syncOrderInfo(order);
	}

	public void syncRequestAndQuote(OrderCustomer orderCustomer, OrderVendor orderVendor) {
		List<OrderRequest> orderRequests = orderCustomer.getOrderRequests();
		for (int i = 0; i < orderRequests.size(); i++) {
			OrderRequest orderRequest = orderRequests.get(i);
			OrderQuote orderQuote = getOrderQuote(orderVendor, orderRequest);
			if (orderQuote == null) {
				orderQuote = new OrderQuote();
				orderQuote.setOrderVendor(orderVendor);
				orderQuote.setOrderRequest(orderRequest);
				saveOrUpdate(orderQuote);
			}
		}
	}

	public void syncRequestAndQuote(OrderCustomer orderCustomer) {
		List<OrderVendor> vendors = orderCustomer.getOrder().getVendors();
		for (int i = 0; i < vendors.size(); i++) {
			syncRequestAndQuote(orderCustomer, vendors.get(i));
		}
		syncOrderInfo(orderCustomer.getOrder());
	}

	private void syncOrderInfo(Order order) {
		order = getOrder(order.getId());

		int productNum = findHQLQueryCount("SELECT sum(request.count) FROM " + OrderRequest.class.getName() + " request WHERE request.orderCustomer.order.id=?", new String[] { order.getId() });
		order.setProductCount(productNum);

		int customerCount = findHQLQueryCount("SELECT count(*) FROM " + OrderCustomer.class.getName() + "  WHERE order.id=?", new String[] { order.getId() });
		order.setCustomerCount(customerCount);

		int vendorCount = findHQLQueryCount("SELECT count(*) FROM " + OrderVendor.class.getName() + "  WHERE order.id=?", new String[] { order.getId() });
		order.setVendorCount(vendorCount);

		saveOrder(order);
	}

	public OrderQuote getOrderQuote(OrderVendor orderVendor, OrderRequest orderRequest) {
		String sql = "FROM " + OrderQuote.class.getName() + " WHERE orderVendor.id = ? AND orderRequest.id = ? ";
		List<OrderQuote> orderQuotes = getHibernateTemplate().find(sql, new Object[] { orderVendor.getId(), orderRequest.getId() });
		if (orderQuotes != null && orderQuotes.size() > 0)
			return orderQuotes.get(0);

		logger.debug("No Order Quote found");
		return null;
	}

	public OrderVendor joinOrderAsVendor(Order order, User user) {
		if (!canJoinAsVendor(order.getId(), user.getId())) {
			throw new ServiceException(ExceptionCode.ORDER_JOIN_NOT_ALLOW, "");
		}
		OrderVendor orderVendor = getOrderVendor(order, user);
		if (orderVendor == null) {
			orderVendor = new OrderVendor();
			orderVendor.setOrder(order);
			List<Company> companies = companyManager.getRegionCompanies(user, order.getVendorRegion().getId());
			if (companies == null || companies.size() == 0) {
				throw new ServiceException(ExceptionCode.USER_NO_COMPANY, "");
			}
			orderVendor.setCompany(companies.get(0));
			getHibernateTemplate().save(orderVendor);
			order.setVendorCount(order.getVendors().size());
			saveOrder(order);

			/* sync */
			syncRequestAndQuote(order, orderVendor);
		}
		return orderVendor;
	}

	public OrderVendor getOrderVendor(Order order, User user) {
		String hql = "FROM " + OrderVendor.class.getName() + " WHERE order.id=? AND company.user.id= ?";
		List<OrderVendor> result = getHibernateTemplate().find(hql, new Object[] { order.getId(), user.getId() });
		if (result != null && result.size() > 0)
			return result.get(0);

		logger.debug("No Order Vendor found");
		return null;
	}

	public OrderVendor getOrderVendor(Order order, String vendorId) {
		String hql = "FROM " + OrderVendor.class.getName() + " WHERE order.id=? AND id= ?";
		List<OrderVendor> result = getHibernateTemplate().find(hql, new Object[] { order.getId(), vendorId });
		if (result != null && result.size() > 0)
			return result.get(0);

		logger.debug("No Order Vendor found");
		return null;
	}

	public boolean canJoinAsCustomer(String orderId, String userId) {
		Order order = getOrder(orderId);
		User user = userManager.getUser(userId);
		OrderVendor orderVendor = getOrderVendor(order, user);
		return orderVendor == null;
	}

	public boolean canJoinAsVendor(String orderId, String userId) {
		OrderCustomer orderCustomer = getOrderCustomer(orderId, userId);
		if (orderCustomer != null)
			return false;
		User user = userManager.getUser(userId);
		Order order = getOrder(orderId);
		List<Company> accreditedCompanies = companyManager.getRegionCompanies(user, order.getVendorRegion().getId());
		if (accreditedCompanies == null || accreditedCompanies.size() == 0)
			return false;
		OrderVendor orderVendor = getOrderVendor(order, user);
		return orderVendor == null;
	}

	public boolean canChangeOrderStatus(Order order) {
		/*------------------------*/
		if (order.isSaved()) {
			logger.debug("The status of Order[" + order.getId() + "] is saved");
			return true;
		}
		/*------------------------*/
		else if (order.isInviting()) {
			if (order.getProductCount() < order.getMinProductNum()) {
				logger.debug("Order[" + order.getId() + "]" + order.getProductCount() + "<" + order.getMinProductNum() + " [order.getProductCount() < order.getMinProductNum()]");
				return false;
			}
		}
		/*------------------------*/
		else if (order.isQuoting()) {
			List<OrderVendor> vendors = order.getVendors();
			int validVendorNum = 0;
			for (int i = 0; i < vendors.size(); i++) {
				if (vendors.get(i).hasAllQuote())
					validVendorNum++;
			}

			if (validVendorNum < order.getMinVendorNum() || validVendorNum < (vendors.size() / 2) + 1) {
				logger.debug("Order[" + order.getId() + "] validVendorNum < order.getMinVendorNum() || validVendorNum < (vendors.size() / 2) + 1");
				return false;
			}
		}
		/*------------------------*/
		else if (order.isVoting()) {
			String hql = "SELECT count(*) FROM " + OrderCustomer.class.getName() + " WHERE order.id=? and votedVendor is not null";
			int count = findHQLQueryCount(hql, new Object[] { order.getId() });
			if (count < (order.getCustomerCount() / 2 + 1) || (order.getVoteDeadline() != null && order.getVoteDeadline().after(new Date()))) {
				logger.debug("Order[" + order.getId() + "]: voteCount < (order.getCustomerCount() / 2 + 1) || (order.getVoteDeadline() != null && order.getVoteDeadline().after(new Date()))");
				return false;
			}
		}
		/*------------------------*/
		else if (order.isCanceled() || order.isClosed()) {
			logger.debug("Order[" + order.getId() + "]: order.isCanceled() || order.isClosed()");
			return false;
		}
		return true;
	}

	public void changeOrderStatus(Order order) throws ServiceException {
		if (!canChangeOrderStatus(order))
			throw new ServiceException(ExceptionCode.ORDER_STATUS_CHANGE_ERROR, "Can't change order[" + order.getId() + "] status now!");
		OrderStatus status = order.getStatus();
		if (status.compareTo(OrderStatus.CLOSED) < 0) {
			if (order.isVoting()) {
				String hql = "SELECT customer.votedVendor FROM " + OrderCustomer.class.getName() + " customer WHERE customer.order.id=? GROUP BY customer.votedVendor ORDER BY count(*) desc";
				List<OrderVendor> result = getHibernateTemplate().find(hql, new Object[] { order.getId() });
				if (result != null && result.size() > 0) {
					order.setVotedVendor(result.get(0));
				} else {
					logger.error("No voted record!");
					throw new ServiceException(ExceptionCode.ORDER_STATUS_CHANGE_ERROR, "Can't change order[" + order.getId() + "] status now!");
				}
			}

			OrderStatus newStatus = OrderStatus.getObj(status.getCode() + 1);
			order.setStatus(newStatus);
			if (newStatus.equals(OrderStatus.CONFIRMED)) {
				order.setComfirmDate(new Date());
			}
			saveOrder(order);

			orderNotifier.orderStausChangeNotify(order);
		}
	}

	public boolean isOrderCustomer(Order order, User user) {
		String hql = "SELECT count(*) FROM " + OrderCustomer.class.getName() + " WHERE order.id=? AND user.id= ?";
		int count = findHQLQueryCount(hql, new Object[] { order.getId(), user.getId() });
		return count > 0;
	}

	public boolean isOrderVendor(Order order, User user) {
		String hql = "SELECT count(*) FROM " + OrderVendor.class.getName() + " WHERE order.id=? AND company.user.id= ?";
		int count = findHQLQueryCount(hql, new Object[] { order.getId(), user.getId() });
		return count > 0;
	}

	public List<Order> getVendedOrders(User user, Page page) {
		String hql = "from " + Order.class.getName() + " o where o.id in (SELECT vendor.order.id FROM " + OrderVendor.class.getName()
				+ " vendor WHERE vendor.company.user.id=?) ORDER BY o.creationTime desc";
		return findHQLQuery(hql, new Object[] { user.getId() }, page);
	}

	public List<OrderVendor> getOrderVendors(User user, Page page) {
		String hql = "FROM " + OrderVendor.class.getName() + " vendor WHERE vendor.company.user.id=? ORDER BY vendor.order.creationTime desc";
		return findHQLQuery(hql, new Object[] { user.getId() }, page);
	}

	public List<TempCategory> getCategoryCount(String cateId, String key, String regionId, int level) {

		int NEED_CHECK = 0;
		int NOT_NEED_CHECK = 1;
		if (StringTools.isBlankOrNull(cateId) && StringTools.isBlankOrNull(key))
			return null;

		if (StringTools.isNotBlankOrNull(regionId) && !Region.GLOBAL_REGION.equals(regionId)) {
			regionId = regionId + "%";
		} else {
			regionId = Region.GLOBAL_REGION;
		}

		int cateFlag = NOT_NEED_CHECK;
		if (StringTools.isNotBlankOrNull(cateId)) {
			cateFlag = NEED_CHECK;
		}
		int titleFlag = NOT_NEED_CHECK;
		if (StringTools.isNotBlankOrNull(key)) {
			titleFlag = NEED_CHECK;
			key = "%" + key + "%";
		}

		if (level > 3)
			level = 3;
		String queryName = "findCategoryCount_level_" + level;
		return findNameQuery(queryName, new Object[] { regionId, regionId, titleFlag, key, cateFlag, cateId }, null);
	}

	public List<Order> findOrdersByCategory(String category, OrderStatus[] statuses, Page page) {
		String sql = " FROM " + Order.class.getName() + " WHERE category.parent.parent.id=? ";
		List<Object> params = new ArrayList<Object>();
		params.add(category);
		sql += " and status in(?";
		params.add(statuses[0]);
		for (int i = 1; i < statuses.length; i++) {
			sql += ",?";
			params.add(statuses[i]);
		}
		sql += ")";
		return findHQLQuery(sql, params.toArray(), page);
		// Criteria criteria = getSession().createCriteria(Order.class);
		// criteria = criteria.add(Restrictions.eq("category.parent.id", category));
		// criteria = criteria.add(Restrictions.in("status", statuses));
		// return criteria.list();
	}

	public void setPropertyManager(IPropertyManager propertyManageService) {
		this.propertyManager = propertyManageService;
	}

	public void setUserManager(IUserManager userManager) {
		this.userManager = userManager;
	}

	public void setCompanyManager(ICompanyManager companyManager) {
		this.companyManager = companyManager;
	}

	public void setOrderNotifier(IOrderNotifier orderNotifier) {
		this.orderNotifier = orderNotifier;
	}

	public void setCategoryManager(ICategoryManager categoryManager) {
		this.categoryManager = categoryManager;
	}

}
